﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Runtime.Serialization;

namespace Galaxy.ModuleInterface.Messages.Source
{
    /// <summary>Источник сообщения</summary>
    [DebuggerDisplay("Сообщение от = {ModuleName}")]
    [Serializable]
    public class CModuleSource : IModuleSource, ISource, ICloneable, ISerializable
    {
        /* ---------------------------------------------------------------------- */

        /// <summary>Модуль источника сообщения</summary>
        private IGalaxyModule f_SourceModule;

        /// <summary>Альтернативное поле имени источника сообщения</summary>
        private string f_ModuleName = "";

        /* ---------------------------------------------------------------------- */

        /// <summary>Модуль источника сообщения</summary>
        public IGalaxyModule Module { get { return f_SourceModule; } }

        /// <summary>Имя источника сообщения</summary>
        public string ModuleName
        {
            get { return f_SourceModule == null ? f_ModuleName : f_SourceModule.Name; }
        }

        /* ---------------------------------------------------------------------- */

        /// <summary>Новый источник сообщения</summary>
        /// <param name="Module">Модуль - источник сообщения</param>
        public CModuleSource(IGalaxyModule Module)
        {
            f_SourceModule = Module;
        }

        /// <summary>Новый источник сообщения из контекста сериализации</summary>
        /// <param name="info">Сериализационная информация</param>
        /// <param name="context">Контекст сериализации</param>
        protected CModuleSource(SerializationInfo info, StreamingContext context)
        {
            f_ModuleName = info.GetString("ModuleName");
        }

        /* ---------------------------------------------------------------------- */

        /// <summary>Сравнение с объектом</summary>
        /// <param name="obj">Сравниваемый объект</param>
        /// <returns>Истина, если объект эквивалентен модулю-источнику, или ХЕШ-коды источников одинаковые</returns>
        public override bool Equals(object obj)
        {
            if( obj is IGalaxyModule ) return obj.Equals(f_SourceModule);
            if( obj is CModuleSource ) return obj.GetHashCode() == this.GetHashCode();

            return base.Equals(obj);
        }

        /// <summary>ХЕШ-код источника</summary>
        /// <returns>ХЕШ-код модуля-источника</returns>
        public override int GetHashCode()
        {
            return f_SourceModule != null ? f_SourceModule.GetHashCode() : f_ModuleName.GetHashCode();
        }

        /// <summary>Преобразование в строковый вид</summary>
        /// <returns>Преобразование в строковый вид</returns>
        public override string ToString()
        {
            return f_SourceModule != null ? f_SourceModule.ToString() : f_ModuleName;
        }

        /// <summary>Клонирование источника</summary>
        /// <returns>Источник сообщения</returns>
        public virtual object Clone() { return this.MemberwiseClone(); }

        /* ---------------------------------------------------------------------- */

        #region ISerializable Members

        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("ModuleName", this.ModuleName);
        }            

        #endregion
    }
}
